package com.yss.reportworld.controller;

import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yss.common.core.constant.RequestDataHelper;
import com.yss.common.core.enums.YssStatusEnum;
import com.yss.common.core.utils.StringUtils;
import com.yss.common.core.utils.easyexecl.EasyExeclUtil;
import com.yss.reportworld.domain.Table;
import com.yss.reportworld.domain.TableDetail;
import com.yss.reportworld.enums.ReportWorldEnum;
import com.yss.reportworld.service.ISqlScriptService;
import com.yss.reportworld.service.ITableDetailService;
import com.yss.reportworld.service.ITableService;
import com.yss.reportworld.util.TableInfoUtil;
import oracle.jdbc.proxy.annotation.Post;
import org.springframework.validation.annotation.Validated;
import com.yss.common.core.utils.uuid.IdUtils;
import com.yss.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yss.common.logger.annotation.Log;
import com.yss.common.logger.enums.BusinessType;
import com.yss.common.security.annotation.RequiresPermissions;
import com.yss.reportworld.domain.DataMap;
import com.yss.reportworld.service.IDataMapService;
import com.yss.common.core.web.controller.BaseController;
import com.yss.common.core.web.domain.AjaxResult;
import com.yss.common.core.web.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 报表世界数据地图Controller
 *
 * @author yss
 * @date 2023-05-25
 */
@RestController
@RequestMapping("/datamap")
public class DataMapController extends BaseController {
    @Autowired
    private IDataMapService dataMapService;
    @Autowired
    private ITableService tableService;
    @Autowired
    private ITableDetailService tableDetailService;
    @Autowired
    private ISqlScriptService sqlScriptService;

    /**
     * 查询报表世界数据地图列表
     */
    @RequiresPermissions("reportworld:datamap:list")
    @GetMapping("/list")
    public TableDataInfo list(DataMap dataMap) {
        startPage();
        List<DataMap> list = dataMapService.selectDataMapList(dataMap);
        return getDataTable(list);
    }

    /**
     * 导出报表世界数据地图列表
     */
    @RequiresPermissions("reportworld:datamap:export")
    @Log(title = "报表世界数据地图", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, DataMap dataMap) {
        List<DataMap> list = dataMapService.selectDataMapList(dataMap);
        EasyExeclUtil.export(response, list, DataMap.class);
    }

    /**
     * 导出报表世界数据地图列表
     */
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        EasyExeclUtil.export(response, null, DataMap.class);
    }


    /**
     * 初始化 加载
     */
    @RequiresPermissions("reportworld:datamap:list")
    @Log(title = "报表世界数据地图", businessType = BusinessType.OTHER)
    @PostMapping("/init")
    public AjaxResult init(@RequestBody DataMap dataMap) {
        try {
            TableInfoUtil.handleTableVersion(dataMap.getHisVersion()); // 替换表名
            AjaxResult ajax = AjaxResult.success();
            QueryWrapper<Table> wrapper = new QueryWrapper<>();
            wrapper.eq("STATUS", YssStatusEnum.NORMAL.getCode());
            wrapper.orderByAsc("NAME");
            ajax.put("tables", tableService.list(wrapper));
            ajax.put("hisVersions", sqlScriptService.getReductionVersion(false));
            return ajax;
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 初始化 加载
     */
    @RequiresPermissions("reportworld:datamap:list")
    @Log(title = "报表世界数据地图", businessType = BusinessType.OTHER)
    @PostMapping("/getTableDetailByTableName")
    public AjaxResult getTableDetailByTableName(@RequestBody DataMap dataMap) {
        try {
            TableInfoUtil.handleTableVersion(dataMap.getHisVersion()); // 替换表名
            AjaxResult ajax = AjaxResult.success();
            QueryWrapper<Table> wrapper = new QueryWrapper<>();
            wrapper.eq("STATUS", YssStatusEnum.NORMAL.getCode());
            wrapper.eq("NAME", dataMap.getTableName());
            Table table = tableService.getOne(wrapper);
            if (StringUtils.isNull(table)) {
                return ajax;
            }
            QueryWrapper<TableDetail> wrapperDetail = new QueryWrapper<>();
            wrapperDetail.eq("TABLE_ID", table.getId());
            wrapperDetail.notIn("COLUMN_NAME", Arrays.asList(ReportWorldEnum.SYS_COLUMN_NAME.getCode().split(",")));
            wrapperDetail.eq("PRIMARY_KEY", 2);
            wrapperDetail.orderByAsc("ORDER_NUM");
            List<TableDetail> list = tableDetailService.list(wrapperDetail);
            ajax.put("tableDetails", list);
            return ajax;
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    @RequiresPermissions("reportworld:datamap:img")
    @Log(title = "报表世界数据地图", businessType = BusinessType.OTHER)
    @PostMapping("/getDataMapImg")
    public AjaxResult getDataMapImg(@RequestBody DataMap dataMap) {
        try {
            TableInfoUtil.handleTableVersion(dataMap.getHisVersion()); // 替换表名
            AjaxResult ajax = AjaxResult.success();
            Map<String, Object> map = new HashMap<>();
            Map<String, String> stringMap = new HashMap<>();
            stringMap.put("name", "example");
            stringMap.put("author", "dd@163.com");
            stringMap.put("version", "0.2");
            map.put("meta", JSONObject.toJSONString(stringMap, SerializerFeature.WriteMapNullValue));
            map.put("format", "node_array");
            map.put("data", dataMapService.querMindTreeNode(dataMap.getTableName()));
            return ajax.put("mindTreeNode", map);
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 获取报表世界数据地图详细信息
     */
    @RequiresPermissions("reportworld:datamap:query")
    @Log(title = "报表世界数据地图", businessType = BusinessType.DELETE)
    @PostMapping(value = "/getDatamap")
    public AjaxResult getDatamap(@RequestBody DataMap dataMap) {
        try {
            TableInfoUtil.handleTableVersion(dataMap.getHisVersion()); // 替换表名
            return success(dataMapService.getById(dataMap.getId()));
        } finally {
            RequestDataHelper.removeThreadLocal();
        }

    }

    /**
     * 新增报表世界数据地图
     */
    @RequiresPermissions("reportworld:datamap:add")
    @Log(title = "报表世界数据地图", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody @Validated DataMap dataMap) {
        try {
            TableInfoUtil.handleTableVersion(dataMap.getHisVersion()); // 替换表名
            if (!dataMapService.checkDataMapUnique(dataMap)) {
                return error("数据已存在，请检查后重试！");
            }
            if (dataMap.getTableName().equals(dataMap.getTableNameRely())) {
                return error("表名和依赖表名不能相同，请检查后重试！");
            }
            dataMap.setId(IdUtils.fastSimpleUUID());
            dataMap.setCreateBy(SecurityUtils.getUsername());
            dataMap.setCreateTime(new Date());
            return toAjax(dataMapService.save(dataMap));
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 修改报表世界数据地图
     */
    @RequiresPermissions("reportworld:datamap:edit")
    @Log(title = "报表世界数据地图", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody @Validated DataMap dataMap) {
        try {
            TableInfoUtil.handleTableVersion(dataMap.getHisVersion()); // 替换表名
            if (!dataMapService.checkDataMapUnique(dataMap)) {
                return error("数据已存在，请检查后重试");
            }
            if (dataMap.getTableName().equals(dataMap.getTableNameRely())) {
                return error("表名和依赖表名不能相同，请检查后重试！");
            }
            dataMap.setUpdateTime(new Date());
            dataMap.setUpdateBy(SecurityUtils.getUsername());
            return toAjax(dataMapService.updateById(dataMap));
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 删除报表世界数据地图
     */
    @RequiresPermissions("reportworld:datamap:remove")
    @Log(title = "报表世界数据地图", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    public AjaxResult remove(@RequestBody DataMap dataMap) {
        try {
            TableInfoUtil.handleTableVersion(dataMap.getHisVersion()); // 替换表名
            return toAjax(dataMapService.removeByIds(dataMap.getIdList()));
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }


    /**
     * 读取报表世界数据地图
     */
    @RequiresPermissions("reportworld:datamap:import")
    @Log(title = "报表世界数据地图", businessType = BusinessType.IMPORT)
    @PostMapping("/readDatamapInfo")
    public AjaxResult readDatamapInfo(MultipartFile file, boolean updateSupport, String hisVersion) throws Exception {
        try {
            TableInfoUtil.handleTableVersion(hisVersion); // 替换表名
            return success(dataMapService.readDatamapInfo(file, updateSupport));
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }


    /**
     * 新增报表世界数据地图
     */
    @RequiresPermissions("reportworld:datamap:get")
    @Log(title = "报表世界数据地图", businessType = BusinessType.INSERT)
    @GetMapping("/getDatamapInfoBySql/{hisVersion}")
    public AjaxResult getDatamapInfoBySql(@PathVariable String hisVersion) {
        return success(dataMapService.getDatamapInfoBySql(hisVersion));
    }
}
